let Camera = require('./camera');
let {vec3, mat4} = require('gl-matrix');
let InputMgr = require('./inputMgr');
let {codes} = require('keycode');


let shaderUtils = require('./shaderUtils');
let objParser = require('./objParser');
let GameItem = require('./gameItem');
let InstanceItem = require('./instanceItem');

const step = 0.4;


let resCache = require('./res/resCache');
let ResItem = require('./res/resItem');
let ResType = require('./res/resType');


let scene = {
    app: null,
    camera: null,
    inputMgr: null,
    items:[],

    loadRes(){
        resCache.addRes(new ResItem('assets/instance.vs.glsl'));
        resCache.addRes(new ResItem('assets/instance.fs.glsl'));
        resCache.addRes(new ResItem('assets/cube.obj'));
        resCache.addRes(new ResItem([
            'assets/skybox/+x.png', 'assets/skybox/-x.png',
            'assets/skybox/+y.png', 'assets/skybox/-y.png',
            'assets/skybox/+z.png', 'assets/skybox/-z.png',
        ], ResType.CubeImage));
    },

    init(app) {

        this.app = app;
        let resCache = app.resCache;
        let gl = app.gl;
        window.gl = gl;
        gl.clearColor(0, 0, 0, 1);

        // init shader
        let vsItem = resCache.getRes('assets/instance.vs.glsl');
        let fsItem = resCache.getRes('assets/instance.fs.glsl');
        let shaderInfo = shaderUtils.buildShader(vsItem.data, fsItem.data);
        shaderUtils.createAttribs(shaderInfo, ['a_position', 'a_offsetPos']);
        shaderUtils.createUniforms(shaderInfo, ['projMatrix', 'mvMatrix']);

        // init obj
        let cubeItem = resCache.getRes('assets/cube.obj');
        let cubeData = objParser.parse(cubeItem.data);

        // 普通 item
        let gameItem = new GameItem(shaderInfo,cubeData);
        this.items.push(gameItem);

        // instance Item
        let insItem = new InstanceItem(shaderInfo,cubeData);
        this.items.push(insItem);

        // init camera
        let pos = vec3.fromValues(0, 0, 5);
        let target = vec3.fromValues(0, 0, 0);
        let up = vec3.fromValues(0, 1, 0);
        this.camera = new Camera(pos, target, up);

        // init input
        this.inputMgr = new InputMgr(this);
    },
    update(dt) {
        this.camera.calProjMatrix(this.app.width,this.app.height);
        this.camera.calViewMatrix();
    },
    render() {
        let gl = window.gl;
        let camera = this.camera;
        gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

        //
        this.items.forEach(item=>{
            item.render(camera);
        });
    },


    //-------------------------------------------
    // key events
    onKeyDown(event) {
        let camera = this.camera;
        switch (event.keyCode) {
            case codes.s:
                camera.translateZ(-step);
                break;
            case codes.w:
                camera.translateZ(step);
                break;
            case codes.a:
                camera.translateX(step);
                break;
            case codes.d:
                camera.translateX(-step);
                break;
        }
    },
    onKeyUp(event) {
    },

    onMouseDown(x, y) {
        console.log(`onMouseDown x:${x},y:${y}`);
    },
    onMouseUp(x, y) {
        console.log(`onMouseUp x:${x},y:${y}`);
    }
};

module.exports = scene;
